package co.th.helper.dao;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.log4j.Logger;

import co.th.helper.common.CommonUtils;
import co.th.helper.jdbc.JdbcTemplate;
import co.th.helper.jdbc.mapper.HospitalRowMapper;
import co.th.helper.model.Hospital;

public class HospitalDAO extends JdbcTemplate<Hospital>{

	private static Logger _logger = Logger.getLogger(HospitalDAO.class);
	
	public List<Hospital> findAll() throws Exception{
		try {
			return findByCriteria(null);
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw new RuntimeException("Can't get all Hospital Data.");
		}
	}
	
	public Hospital findByPK(BigDecimal hospitalCode) throws Exception{
		try {
			Hospital hospital = new Hospital();
			hospital.setHospitalCode(hospitalCode);
			List<Hospital> list = findByCriteria(hospital);
			if (null == list || list.isEmpty()){
				throw new Exception("Record not found.");
			}
			return list.get(0);
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw new RuntimeException("Cat not get Hospital");
		}
	}
	
	public List<Hospital> findByCriteria(Hospital hospital) throws Exception{
		try {
			StringBuffer sql = new StringBuffer("select * from person where 1=1 ");
			List<Object> paramObj = new ArrayList<Object>(0);
			
			if (null != hospital){
				int index = 0;
				if (null != hospital.getHospitalCode() && hospital.getHospitalCode().intValue() > 0){
					sql.append(" , hospital_code = ? ");
					paramObj.add(index++, hospital.getHospitalCode());
				}
				if (!CommonUtils.chkIsnull(hospital.getHospitalNameTH())){
					sql.append(" , hospital_name_th = ? ");
					paramObj.add(index++, hospital.getHospitalNameTH());
				}
				if (!CommonUtils.chkIsnull(hospital.getHospitalNameEN())){
					sql.append(" , hospital_name_en = ? ");
					paramObj.add(index++, hospital.getHospitalNameEN());
				}
				if (!CommonUtils.chkIsnull(hospital.getHospitalType())){
					sql.append(" , hospital_type = ? ");
					paramObj.add(index++, hospital.getHospitalType());
				}
				if (!CommonUtils.chkIsnull(hospital.getAddress())){
					sql.append(" , address = ? ");
					paramObj.add(index++, hospital.getAddress());
				}
				if (!CommonUtils.chkIsnull(hospital.getTelephone())){
					sql.append(" , telephone = ? ");
					paramObj.add(index++, hospital.getTelephone());
				}
				if (!CommonUtils.chkIsnull(hospital.getEmail())){
					sql.append(" , email = ? ");
					paramObj.add(index++, hospital.getEmail());
				}
				if (null != hospital.getPresident() && hospital.getPresident().intValue() > 0){
					sql.append(" , president_code = ? ");
					paramObj.add(index++, hospital.getPresident());
				}
				if (null != hospital.getProvince() && hospital.getProvince().intValue() > 0){
					sql.append(" , province_id = ? ");
					paramObj.add(index++, hospital.getProvince());
				}
				if (null != hospital.getRegion() && hospital.getRegion().intValue() > 0){
					sql.append(" , region_id = ? ");
					paramObj.add(index++, hospital.getRegion());
				}
			}
			return this.queryList(sql.toString(), CommonUtils.convListToArray(paramObj), new HospitalRowMapper());
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw new RuntimeException("Can't get person");
		}
	}
	
	public synchronized Hospital insert(Hospital hospital) throws Exception{
		try {
			hospital.setHospitalCode(genPK());
			
			final String sql = "INSERT INTO hospital (hospital_code, hospital_name_th, hospital_name_en, hospital_type, " +
					"address, telephone, email, president_code, province_id, region_id, " +
					"create_by, create_date, update_by, update_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
			Object[] params = new Object[14];
			params[0] = hospital.getHospitalCode();
			params[1] = hospital.getHospitalNameTH();
			params[2] = hospital.getHospitalNameEN();
			params[3] = hospital.getHospitalType();
			params[4] = hospital.getAddress();
			params[5] = hospital.getTelephone();
			params[6] = hospital.getEmail();
			params[7] = hospital.getPresident();
			params[8] = hospital.getProvince();
			params[9] = hospital.getRegion();
			params[10] = hospital.getCreateBy();
			params[11] = hospital.getCreateDate();
			params[12] = hospital.getUpdateBy();
			params[13] = hospital.getUpdateDate();
			
			int rowOfProcess = this.saveUnique(sql, params);
			if (rowOfProcess < 1){
				throw new Exception("Can't save hospital data.");
			}
			return hospital;
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw ex;
		}
	}
	
	public int update(Hospital hospital) throws Exception{
		try {
			StringBuffer sql = new StringBuffer("UPDATE hospital SET ");
			List<Object> paramObj = new ArrayList<Object>(0);
			
			if (hospital.getHospitalCode() == null || hospital.getHospitalCode().intValue() <= 0){
				throw new Exception("No primary key.");
			}
			
			int index = 0;
			sql.append(" update_date = ?  ");
			paramObj.add(index++, new java.sql.Date(Calendar.getInstance().getTime().getTime()));
			if (!CommonUtils.chkIsnull(hospital.getHospitalNameTH())){
				sql.append(" , hospital_name_th = ? ");
				paramObj.add(index++, hospital.getHospitalNameTH());
			}
			if (!CommonUtils.chkIsnull(hospital.getHospitalNameEN())){
				sql.append(" , hospital_name_en = ? ");
				paramObj.add(index++, hospital.getHospitalNameEN());
			}
			if (!CommonUtils.chkIsnull(hospital.getHospitalType())){
				sql.append(" , hospital_type = ? ");
				paramObj.add(index++, hospital.getHospitalType());
			}
			if (!CommonUtils.chkIsnull(hospital.getAddress())){
				sql.append(" , address = ? ");
				paramObj.add(index++, hospital.getAddress());
			}
			if (!CommonUtils.chkIsnull(hospital.getTelephone())){
				sql.append(" , telephone = ? ");
				paramObj.add(index++, hospital.getTelephone());
			}
			if (!CommonUtils.chkIsnull(hospital.getEmail())){
				sql.append(" , email = ? ");
				paramObj.add(index++, hospital.getEmail());
			}
			if (null != hospital.getPresident() && hospital.getPresident().intValue() > 0){
				sql.append(" , president_code = ? ");
				paramObj.add(index++, hospital.getPresident());
			}
			if (null != hospital.getProvince() && hospital.getProvince().intValue() > 0){
				sql.append(" , province_id = ? ");
				paramObj.add(index++, hospital.getProvince());
			}
			if (null != hospital.getRegion() && hospital.getRegion().intValue() > 0){
				sql.append(" , region_id = ? ");
				paramObj.add(index++, hospital.getRegion());
			}
			sql.append(" WHERE hospital_code = ? ");
			paramObj.add(index++, hospital.getHospitalCode());
			
			return updateUnique(sql.toString(), CommonUtils.convListToArray(paramObj), new HospitalRowMapper());
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw new RuntimeException("Can't update Hospital Data.");
		}
	}
	
	public int delete(BigDecimal hospitalCode) throws Exception{
		try {		
			if (hospitalCode == null || hospitalCode.intValue() <= 0){
				throw new Exception("No primary key (Hospital Code).");
			}
			
			final String sql = "DELETE FROM hospital WHERE hospital_code = ?";
			Object[] param = new Object[]{hospitalCode};
			
			return updateUnique(sql.toString(), param, new HospitalRowMapper());
		} catch (Exception ex) {
			_logger.error("Exception : " + ex.getMessage());
			throw new RuntimeException("Can't delete Hospital Data.");
		}
	}
	
	private BigDecimal genPK() throws Exception{
		final String sql = "select max(hospital_code) AS hospital_code from hospital";
		_logger.debug("SQL : " + sql);
		Hospital objRow = queryUnique(sql, new Object[0], new HospitalRowMapper());
		return BigDecimal.valueOf(objRow.getHospitalCode().intValue() + 1);
	}
}
